#include "music.h"
#include<QUuid>
#include<QMediaPlayer>
#include<QDebug>
#include<QCoreApplication>
#include<QSqlQuery>
#include<QSqlError>

/////////////////////////////////////////////////////////
//描述歌曲音乐,用方便组织管理一个音乐文件//////////////////////
////////////////////////////////////////////////////////

Music::Music()
    :isLike(false)
    ,isHistory(false)
{

}

//通过音乐文件的URL路径创建Music对象-->读取URL对应的歌曲文件信息,解析元数据(名称,作者,专辑,持续时长等)
Music::Music(QUrl url)
    :musicUrl(url)
    ,isLike(false)
    ,isHistory(false)

{
    //提供QUuid类给歌曲赋值ID
    musicId=QUuid::createUuid().toString();
    //读取url对应的歌曲文件(媒体源),解析出元数据(歌曲名称,歌曲作者,歌曲专辑,歌曲持续时长等)并进行相应设置
    parseMediaMetaDate();
}

//提供设置音乐文件的成员变量的函数
void Music::setMusicId(const QString &musicId)
{
    this->musicId=musicId;
}
void Music::setMusicName(const QString& musicName)
{
    this->musicName=musicName;
}
void Music::setMusicSinger(const QString& musicSinger)
{
    this->musicSinger=musicSinger;
}
void Music::setMusicAlbum(const QString& musicAlbum)
{
    this->musicAlbum=musicAlbum;
}
void Music::setDuration(qint64 durable)
{
    this->duration=durable;
}

void Music::setMusicUrl(const QString &musicUrl)
{
    this->musicUrl=musicUrl;
}
void Music::setIsLike(bool isLike)
{
    this->isLike=isLike;
}
void Music::setIsHistory(bool isHistory)
{
    this->isHistory=isHistory;
}

//提供获取音乐文件的成员变量的函数
QString Music::getMusicName()const
{
    return this->musicName;
}
QString Music::getMusicSinger()const
{
    return this->musicSinger;
}
QString Music::getMusicAlbum()const
{
    return this->musicAlbum;
}
qint64 Music::getDuration()const
{
    return this->duration;
}
bool Music::getIsLike()const
{
    return this->isLike;
}
bool Music::getIsHistory()const
{
    return this->isHistory;
}

QUrl Music::getMusicUrl()const
{
    return this->musicUrl;
}

QString Music::getMusicId() const
{
    return this->musicId;
}

//获取当前歌曲对应歌词文件的路径函数
QString Music::getLrcFilePath() const
{
    QString lrcPath=musicUrl.toLocalFile();//获取当前歌曲文件的路径
    lrcPath.replace(".mp3",".lrc"); //QString类提供replace()方法替换字符串
    lrcPath.replace(".flac",".lrc");
    lrcPath.replace(".mpga",".lrc");
    return lrcPath;
}

//把歌曲信息写入到数据库中
void Music::writeMusicToDB()
{
    //检测music是否在数据库中存在
    QSqlQuery query;
    //在musicInfo表中查询歌曲musicId等于指定值的歌曲,如果歌曲存在,返回记录中只包含一个1
    //select exists(子查询):如果子查询中有记录,返回true
    //                     如果子查询中没有记录,返回false
    query.prepare("select exists(select 1 from musicInfo where musicId= ?)");
    query.addBindValue(musicId);
    if(!query.exec())
    {
        qDebug()<<"查询失败"<<query.lastError().text();
        return;
    }

    //调用next()函数拿到查询记录
    if(query.next())
    {
        //判断music记录是否存在数据库中
        bool isExists=query.value(0).toBool();
        if(isExists)
        {
            //存在则更新歌曲信息
            query.prepare("update musicInfo set isLike=?,isHistory=? where musicId=?");
            query.addBindValue(isLike?1:0);
            query.addBindValue(isHistory?1:0);
            query.addBindValue(musicId);
            if(!query.exec())
            {
                qDebug()<<"更新结果失败"<<query.lastError().text();
                return;
            }
            qDebug()<<"更新结果成功";
        }
        else
        {
            //不存在则插入歌曲信息
            query.prepare("insert into musicInfo(musicId, musicName, musicSinger, albumName, duration, musicUrl, isLike, isHistory) values(?,?,?,?,?,?,?,?)");
            query.addBindValue(musicId);
            query.addBindValue(musicName);
            query.addBindValue(musicSinger);
            query.addBindValue(musicAlbum);
            query.addBindValue(duration);
            query.addBindValue(musicUrl.toLocalFile());
            query.addBindValue(isLike?1:0);
            query.addBindValue(isHistory?1:0);
            if(!query.exec())
            {
                qDebug()<<"插入失败"<<query.lastError().text();
                return;
            }
            qDebug()<<"插⼊music信息: "<<musicName<<" "<<musicId;
        }
    }
}

//解析媒体的元数据
void Music::parseMediaMetaDate()
{
    //创建媒体播放对象
    QMediaPlayer player;
    //设置播放源(媒体数据从中读取)-->用QUrl对象构造成QMediaPlayer类的匿名对象,传参到setMedia()函数中,将musicUrl对应的音乐设置为播放源
    player.setMedia(musicUrl);//该函数立马返回,不会等待媒体加载完成
    // 媒体元数据解析需要时间，只有等待解析完成之后，才能提取⾳乐信息，此处循环等待
    // 循环等待时：主界⾯消息循环就⽆法处理了，因此需要在等待解析期间，让消息循环继续处理
    while(!player.isMetaDataAvailable())//死循环(判断媒体元是否有效)---这里阻塞了Qt框架被阻塞
    {
        QCoreApplication::processEvents();      //QCoreApplication提供processEvents()让Qt框架的事件循环运行起来,不会被阻塞
    }
    if(player.isMetaDataAvailable())
    {
        musicName=player.metaData("Title").toString();      //QMediaPlayer类中提供metaData()方法,可以从播放源中解析出媒体的元数据(描述媒体的一些数据,eg:名称,作者,专辑,时长等信息)
        musicSinger=player.metaData("Author").toString();   //会返回QVariant类(把不同数据类型进行一个包装的类)对象,还需要通过相关函数,把QVariant类型转化成对应的类型
        musicAlbum=player.metaData("AlbumTitle").toString();
        duration=player.metaData("Duration").toLongLong();

        //处理元数据为空的情况
        QString fileNmae=musicUrl.fileName();   //获取文件的名字
        int index=fileNmae.indexOf('-');        //返回文件名字中第一次出现'-'的下标
        //歌曲名称为空的时候
        if(musicName.isEmpty())
        {
            if(index!=-1)
            {
                //2002年的第一场雪 - 刀郎.mp3 -->文件名情况一
                musicName=fileNmae.mid(0,index).trimmed();  //mid()可以帮助我们截取字符,从下标开始截取N个字符,trimmed()可以帮我们去除字符串前后的空白字符串
            }
            else
            {
                //2002年的第一场雪.mp3 -->文件名情况二
                musicName=fileNmae.mid(0,fileNmae.indexOf('.')).trimmed();
            }
        }
        //歌曲歌手为空的时候
        if(musicSinger.isEmpty())
        {
            if(index!=-1)
            {
                musicSinger=fileNmae.mid(index+1,fileNmae.indexOf('.')-index-1).trimmed();
            }
            else
            {
                musicSinger="未知歌手";
            }
        }
        //歌曲专辑为空的时候
        if(musicAlbum.isEmpty())
        {
            musicAlbum="未知专辑";
        }

        qDebug()<<musicName<<":"<<musicSinger<<":"<<musicAlbum<<":"<<duration;
    }
}
